Skip to content

로그아웃·탈퇴 시 로컬 저장소 잔존 수정 — DataStore 수명(scope) 계약 도입 - #931

Merged
OnlyReadOneBook merged 6 commits into
developfrom
fix/912
Aug 24, 2026
Merged

OnlyReadOneBook merged 6 commits into
developfrom
fix/912

Conversation

@OnlyReadOneBook

Copy link
Copy Markdown
Collaborator

Closes #912

변경

  • core:datastore 에 StoreScope(SESSION/DEVICE) · LocalStoreRegistry 신설 — 모든 Preferences DataStore 는 registry.store(name, scope) 로만 얻고, 획득 시점에 수명이 함께 등록된다. 반환 타입은 DataStore<Preferences> 그대로라 원자적 다중 키 edit 등 API 를 좁히지 않는다 (사전 검토 코멘트 ③ 반영).
  • (name→scope) 등록을 매니페스트 파일에 영속 — Hilt provider 는 최초 주입 때에야 실행되므로 in-memory 등록만으로는 "이전 프로세스에서 기록되고 이번 프로세스에선 아직 안 열린" 저장소를 clearScope 가 놓친다 (코멘트 ②). 레지스트리 재생성으로 프로세스 재시작을 흉내 내는 테스트가 이 경로를 직접 가드한다.
  • logout()·clearSession() 이 clearScope(SESSION) 호출. 탈퇴(deleteAccount)도 clearSession 경유라 함께 정리된다 (코멘트 ①). "정리는 서버 호출 뒤" 순서 계약 유지.
  • 4개 저장소 전부 SESSION 확정. 이슈에서 보류였던 IdentityVerification 도 SESSION — 인증 기록이 로컬 boolean 뿐이라 계정 전환을 감지하지 못하므로, 로그아웃 시 지워 다음 계정이 이전 사용자의 본인인증 완료를 승계하지 못하게 한다. 같은 사람의 재로그인 시 재인증은 감수 (어사이니 결정, 확인 필요 항목 해소).
  • DataStore name·경로는 한 글자도 안 바꿨다 (필수 주의 준수 — 기존 사용자 데이터 연속). 레지스트리가 기존 델리게이트와 같은 preferencesDataStoreFile 경로를 쓴다.
  • 프로덕션 호출자 0 인 UserProfileRepository.clear() · ReceiverRepository.clearAuthCode() · TokenDataSource.clearTokens() · ReceiverAuthCodeDataSource.clearCode() 와 테스트 fake 오버라이드 제거. Context 델리게이트 파일 4개 삭제.

검증

  • ./gradlew testDebugUnitTest ktlintCheck 전 모듈 green (origin/develop 머지 후 기준). 신규 LocalStoreRegistryImplTest 6건 — 재기동 시뮬레이션·scope 충돌·인스턴스 공유 가드. AuthRepositoryImplTest 15건 갱신 — "서버 호출이 정리보다 먼저" 순서 가드 포함.
  • :app:compileDebugAndroidTestKotlin — 이번 인터페이스 축소로 깨지는 androidTest fake 3곳(clearAuthCode 2·clear 1) 정리. 나머지 실패 44건은 순수 origin/develop 에서 동일 재현되는 기존 결함 — 라인 번호 무시 에러 집합 대조로 본 브랜치 신규 깨짐 0건을 확인했다. androidTest 컴파일이 PR CI 게이트에 없어 미검증 착륙한 것으로 보이며, [test] #835 Gradle Managed Device 전 범위 androidTest 도입 #861/[test] #836 구현된 기능 경로 androidTest 커버리지 완성 #867 스택 소관이라 본 PR 범위 밖.
  • 시각 검증 skip — diff 29개 파일 전부 data/domain/datastore/테스트, Compose 본문·리소스 변경 없음.
  • 에뮬 실측 미실행 (재량 판단) — 등록·정리 로직은 실파일 DataStore 기반 JVM 테스트가 재기동 경로까지 커버하고, 남는 경계는 Hilt 배선인데 이는 컴파일·바인딩 검증으로 확인된다. 실기기 확인이 필요하면 로그인 계정으로 별도 진행 가능.

리뷰어 참고

  • DataStore 의 "파일당 활성 인스턴스 1개" 강제는 공식 문서 명시 사항 — 레지스트리의 인스턴스 캐시(와 clearScope 가 연 저장소도 캐시에 넣는 처리)가 이를 보장한다. 팩토리 + Hilt @Provides @Singleton 제공 방식은 NiA 의 DataStoreModule 과 동형이다.
  • scope 충돌 시 정책: 코드 vs 코드 불일치는 즉시 크래시(버그 조기 발견), 매니페스트(과거 기록) vs 코드 불일치는 코드 채택(앱 업데이트로 scope 가 바뀌어도 안 죽음) — Entry.registeredByCode 가 이 둘을 가른다.

로그아웃 정리 대상을 저장소마다 clear 로 각자 노출하고 호출해 주기를
기대하던 구조를 걷어내는 1단계. 수명 계약과 테스트를 들이고, 프로덕션
호출자가 0 이던 저장소별 정리 메서드와 Context 델리게이트를 제거한다.
레지스트리 구현체·DI 배선·logout() 연결은 후속 커밋에서.

- core:datastore 에 StoreScope(SESSION/DEVICE)·LocalStoreRegistry 계약 신설
- preferencesDataStore Context 델리게이트 4개 삭제 (파일명·경로 계약은
  후속 커밋의 레지스트리 배선이 그대로 승계)
- UserProfileRepository.clear()·ReceiverRepository.clearAuthCode()·
  TokenDataSource.clearTokens()·ReceiverAuthCodeDataSource.clearCode() 와
  테스트 fake 오버라이드 제거
- 레지스트리 계약 테스트(프로세스 재기동 시뮬레이션 포함)와 세션 일괄
  정리 단언 추가

주의: 이 커밋 단독으로는 빌드되지 않는다 (구현·배선은 후속 커밋).
- LocalStoreRegistryImpl — (name→scope) 등록을 매니페스트 파일에 영속해,
  Hilt lazy 주입으로 이번 프로세스에서 아직 안 열린 저장소도 clearScope 가
  열어서 지운다
- DI 모듈 4개를 registry.store(name, scope) 경유로 전환 — 파일명·경로
  불변(기존 사용자 데이터 연속), 반환은 DataStore<Preferences> 그대로라
  원자적 다중 키 edit 보존
- 4개 전부 SESSION 확정. IdentityVerification 도 SESSION — 인증 기록이
  로컬 boolean 뿐이라 계정 전환을 감지 못 하므로, 로그아웃 시 지워 타
  계정의 인증 상태 승계를 막는다 (재로그인 시 재인증 감수, #912 확인
  필요 항목 해소)
- logout()·clearSession() 이 clearScope(SESSION) 호출 — 탈퇴(deleteAccount)
  경로도 clearSession 을 쓰므로 함께 정리. 서버 호출 뒤 정리 순서 유지
develop 머지로 들어온 androidTest fake 3곳(ReceiverRepository 2, UserProfileRepository 1)이
#912 에서 제거된 인터페이스 메서드를 override 하고 있어 정리한다.
:app:compileDebugAndroidTestKotlin 의 나머지 실패 44건은 순수 origin/develop 에서도
동일 재현되는 기존 결함 — 에러 집합 대조로 본 브랜치 신규 깨짐 0건 확인.
…경로에서 registry 로 제공

#919 가 IdentityVerification·ReceiverAuthCode DataStore 를 :feature:afternote:data 에서
:feature:receiver:data 로 옮겼고, #912 는 같은 파일들을 삭제하고 LocalStoreRegistry 로 대체했다.

- di 모듈 2종: 이관된 신규 패키지에서 registry.store(scope = SESSION) 제공을 유지
- *PreferencesDataStore.kt 2종: #912 의 삭제 유지 (rename/delete 충돌 — 이관본도 삭제)

검증: :app:compileDebugUnitTestKotlin, :core:datastore:ktlintCheck,
:feature:receiver:data:ktlintCheck 통과.
:app:compileDebugAndroidTestKotlin 은 develop 단독(495ebaf)에서도 44건 실패하는
기존 드리프트로 #949 가 고치는 범위다.
@OnlyReadOneBook
OnlyReadOneBook merged commit e4c9495 into develop Aug 24, 2026
13 checks passed
@OnlyReadOneBook
OnlyReadOneBook deleted the fix/912 branch August 24, 2026 09:16
@github-actions

Copy link
Copy Markdown
Contributor

🚀 QA 배포 권장

QA 포인트

이 판단은 배포를 자동 실행하지 않습니다. deploy일 때 Release Distribution을 수동 실행하세요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

로그아웃 시 로컬 저장소 3개가 지워지지 않음 — DataStore 수명(scope) 계약 도입

2 participants